﻿using BCVP.Net8.Common.app;
using BCVP.Net8.Common.appsettings;
using BCVP.Net8.Common.db;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace BCVP.Net8.Extension.db.init
{
    /// <summary>
    /// SqlSugar 启动服务
    /// </summary>
    public static class SqlsugarSetup
    {
        // 这是一个扩展方法，用于 IServiceCollection 接口
        // 'this' 关键字表示这是对 IServiceCollection 的扩展
        public static void AddSqlsugarSetup(this IServiceCollection services)
        {
            // 1. 参数校验
            // 检查传入的 services 对象是否为空，如果为空则抛出异常
            if (services == null) throw new ArgumentNullException(nameof(services));

            // 2. 设置主数据库连接ID
            // 从配置 (AppSettings) 中读取 "MainDB" 的值
            // 如果该值不为空或空字符串，则将其赋值给 MainDb 类的静态属性 CurrentDbConnId
            if (!string.IsNullOrEmpty(AppSettings.app("MainDB")))
            {
                MainDb.CurrentDbConnId = AppSettings.app("MainDB");
            }

            // 3. 遍历并配置所有数据库连接
            // BaseDBConfig.MutiConnectionString.allDbs 是一个包含多个数据库连接信息的列表
            // 对列表中的每一个数据库配置项 m 执行以下操作:
            BaseDBConfig.MutiConnectionString.allDbs.ForEach(m =>
            {
                // a. 创建 SqlSugar 的 ConnectionConfig 对象
                var config = new ConnectionConfig()
                {
                    // ConfigId: 连接的唯一标识符，通常使用数据库的 ConnId，并转为小写
                    ConfigId = m.ConnId.ObjToString().ToLower(),
                    // ConnectionString: 数据库的连接字符串
                    ConnectionString = m.Connection,
                    // DbType: 数据库类型 (如 MySql, SqlServer 等)，从 m.DbType 转换而来
                    DbType = (DbType)m.DbType,
                    // IsAutoCloseConnection: 是否自动关闭数据库连接，设为 true 提高资源利用率
                    IsAutoCloseConnection = true,
                    // MoreSettings: 更多连接设置
                    MoreSettings = new ConnMoreSettings()
                    {
                        // IsAutoRemoveDataCache: 是否自动移除数据缓存，设为 true
                        IsAutoRemoveDataCache = true,
                        // SqlServerCodeFirstNvarchar: 针对 SqlServer，代码优先时是否使用 nvarchar 类型，设为 true
                        SqlServerCodeFirstNvarchar = true,
                    },
                    // InitKeyType: 主键初始化类型，这里设置为根据特性 (Attribute) 初始化
                    InitKeyType = InitKeyType.Attribute
                };

                // b. 分类存储配置
                // 检查当前数据库连接的 ConnId 是否与预定义的 LogConfigId 相同 (忽略大小写)
                if (SqlSugarConst.LogConfigId.ToLower().Equals(m.ConnId.ToLower()))
                {
                    // 如果是，则将此配置存储为日志数据库的配置
                    BaseDBConfig.LogConfig = config;
                }
                else
                {
                    // 如果不是，则将其添加到常规有效数据库配置列表中
                    BaseDBConfig.ValidConfig.Add(config);
                }

                // c. 将所有配置（无论是 Log 还是 Valid）都添加到一个总列表中
                BaseDBConfig.AllConfigs.Add(config);
            });

            // 4. 校验日志数据库配置
            // 检查是否成功配置了日志数据库连接
            // 如果 BaseDBConfig.LogConfig 仍然是 null，说明配置中没有找到匹配 LogConfigId 的连接
            if (BaseDBConfig.LogConfig is null)
            {
                // 抛出异常，提示未配置日志库连接
                throw new ApplicationException("未配置Log库连接");
            }

            // 5. 注册 SqlSugarScope 到依赖注入容器
            // SqlSugarScope 是 SqlSugar 提供的线程安全的数据库上下文，适合单例模式使用
            // services.AddSingleton<ISqlSugarClient>(...) 将 ISqlSugarClient 接口的实现注册为单例
            services.AddSingleton<ISqlSugarClient>(o =>
            {
                // 返回一个新的 SqlSugarScope 实例，传入之前收集的所有数据库配置 (BaseDBConfig.AllConfigs)
                // 这样，应用的其他部分就可以通过依赖注入获取到 ISqlSugarClient 实例来操作数据库了
                return new SqlSugarScope(BaseDBConfig.AllConfigs);
            });
        }
    }
}
